package sync

import (
	"fmt"
	"sync"
	"time"
)

// DemoMutex 演示互斥锁的使用
func DemoMutex() {
	fmt.Println("=== 互斥锁和同步原语演示 ===")
	fmt.Println("\n--- 互斥锁(Mutex) ---")

	// 共享资源
	counter := 0
	// 互斥锁
	var mutex sync.Mutex

	// 启动多个goroutine访问共享资源
	for i := 0; i < 5; i++ {
		go func(id int) {
			for j := 0; j < 1000; j++ {
				// 加锁
				mutex.Lock()
				// 访问共享资源
				counter++
				// 解锁
				mutex.Unlock()
			}
			fmt.Printf("Goroutine %d 完成\n", id)
		}(i)
	}

	// 等待所有goroutine完成
	time.Sleep(2 * time.Second)
	fmt.Printf("最终计数器值: %d\n", counter)
}

// DemoWaitGroup 演示等待组的使用
func DemoWaitGroup() {
	fmt.Println("\n--- 等待组(WaitGroup) ---")

	var wg sync.WaitGroup

	// 启动多个goroutine
	for i := 0; i < 3; i++ {
		// 增加等待组计数
		wg.Add(1)
		go func(id int) {
			// 减少等待组计数
			defer wg.Done()

			fmt.Printf("Goroutine %d 开始\n", id)
			time.Sleep(time.Duration(id+1) * 500 * time.Millisecond)
			fmt.Printf("Goroutine %d 完成\n", id)
		}(i)
	}

	fmt.Println("等待所有goroutine完成...")
	// 等待所有goroutine完成
	wg.Wait()
	fmt.Println("所有goroutine已完成")
}

// DemoOnce 演示Once的使用
func DemoOnce() {
	fmt.Println("\n--- Once ---")

	var once sync.Once
	initFunc := func() {
		fmt.Println("初始化函数执行")
	}

	// 多次调用，但initFunc只会执行一次
	for i := 0; i < 5; i++ {
		go func(id int) {
			once.Do(initFunc)
			fmt.Printf("Goroutine %d 完成\n", id)
		}(i)
	}

	// 等待所有goroutine完成
	time.Sleep(1 * time.Second)
}

// DemoSyncPrimitives 整合演示所有同步原语
func DemoSyncPrimitives() {
	DemoMutex()
	DemoWaitGroup()
	DemoOnce()
}
